/**
  * Author: Mei
  * Date: 2021-01-10 14:11
  * Description: declval<>()的使用  去除引用
  *
  *  返回一个类型的右值引用，不管是否有没有默认构造函数或该类型不可以创建对象。（可以用于抽象基类）;
  *
  *  a)从类型转换的角度来讲，将任意一个类型转换成右值引用类型。
    b)从假想创建出某类型对象的角度来说，配合decltype，令在decltype表达式中，不必经过该类型的
        构造函数就能使用该类型的成员函数。
    注意，std::declval不能被调用，也不能创建任何对象。
    但std::declval能在不创建对象的情况下，达到创建了一个该类型对象的效果或者说可以
        假定创建出了一个该类型对象。
  *
  */
#include <utility>      // std::declval
#include <iostream>     // std::cout

struct A {              // abstract class
    virtual int value() = 0;
};

class B : public A {    // class with specific constructor
    int val_;
public:
    B(int i,int j):val_(i*j){}
    int value() {return val_;}
};

int main() {
    decltype(std::declval<A>().value()) a;  // int a
    decltype(std::declval<B>().value()) b;  // int b
    decltype(B(0,0).value()) c;   // same as above (known constructor)
    a = b = B(10,2).value();
    std::cout << a << '\n';
    return 0;
}